﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HA.ModFlow.Domain.DomainLayer;
namespace HA.Data
{
    [Serializable]
    public class BCGeneralHead : BCType, ICloneable
    {

        public BCGeneralHead()
            : base()
        {

            //首先保证有一个应力期的值

            //this._multiConductance = new List<double>();


            //this._multiHeadStage = new List<double>();




            //this._multiStartHead = new List<double>();


            //this._multiEndHead = new List<double>();

    



            //for (int i = 0; i < this.NPeriods; i++)
            //{
            //    this._multiConductance.Add(0);
            //    this._multiEndHead.Add(0);
            //    this._multiHeadStage.Add(0);
            //    this._multiStartHead.Add(0);
            //}

        }

        public object Clone()
        {
            BCGeneralHead bcgh=(BCGeneralHead)this.MemberwiseClone();
            bcgh._multiConductance = (BCDateDataCollection)_multiConductance.Clone();


            bcgh._multiEndHead = (BCDateDataCollection)this._multiEndHead.Clone();


            bcgh._multiHeadStage = (BCDateDataCollection)_multiHeadStage.Clone();


            bcgh._multiStartHead = (BCDateDataCollection)_multiStartHead.Clone();

            return bcgh;
        
        }



        BCDateDataCollection _multiConductance = new BCDateDataCollection();

        public BCDateDataCollection MultiConductance
        {
            get { return _multiConductance; }
            set { _multiConductance = value; }
        }

        //double _conductance;

        public double Conductance
        {
            get {
                return this._multiConductance.IsDataConst ? _multiConductance.ConstData : this._multiConductance.BCDatas[0].Value;
            }
            set {

                if (this._multiConductance.IsDataConst)
                    this._multiConductance.ConstData = value;
                else
                    this._multiConductance.BCDatas[0].Value = value;
            }
        }

        //double _headStage;

        public double HeadStage
        {
            get { return this._multiHeadStage.IsDataConst ? _multiHeadStage.ConstData : this._multiHeadStage.BCDatas[0].Value; }
            set
            {
                if (this._multiHeadStage.IsDataConst)
                    this._multiHeadStage.ConstData = value;
                else
                    this._multiHeadStage.BCDatas[0].Value = value;
            }
        }



        BCDateDataCollection _multiHeadStage = new BCDateDataCollection();

        public BCDateDataCollection MultiHeadStage
        {
            get { return _multiHeadStage; }
            set { _multiHeadStage = value; }
        }


        //double _startHead;

        public double StartHead
        {
            get { return this._multiStartHead.IsDataConst ? _multiStartHead.ConstData : this._multiStartHead.BCDatas[0].Value; }
            set
            {
                if (this._multiStartHead.IsDataConst)
                    this._multiStartHead.ConstData = value;
                else
                    this._multiStartHead.BCDatas[0].Value = value;
            }
        }

        BCDateDataCollection _multiStartHead = new BCDateDataCollection();

        public BCDateDataCollection MultiStartHead
        {
            get { return _multiStartHead; }
            set { _multiStartHead = value; }
        }



        //double _endHead;

        public double EndHead
        {
            get { return this._multiEndHead.IsDataConst ? _multiEndHead.ConstData : this._multiEndHead.BCDatas[0].Value; }
            set
            {
                if (this._multiEndHead.IsDataConst)
                    this._multiEndHead.ConstData = value;
                else
                    this._multiEndHead.BCDatas[0].Value = value;
            }
        }


        BCDateDataCollection _multiEndHead = new BCDateDataCollection();

        public BCDateDataCollection MultiEndHead
        {
            get { return _multiEndHead; }
            set { _multiEndHead = value; }
        }


        //public override void OnNPeriodsChanged()
        //{
        //    base.OnNPeriodsChanged();

        //    //取得之前数据的个数
        //    int n = this.MultiConductance.Count;



        //    //开始更新数据


        //    if (n < this.NPeriods)
        //    {
        //        int nSub = this.NPeriods - n;

        //        for (int i = 0; i < nSub; i++)
        //        {
        //            this.MultiConductance.Add(0);
        //            this.MultiEndHead.Add(0);
        //            this.MultiHeadStage.Add(0);
        //            this.MultiStartHead.Add(0);
        //        }
        //    }

        //    else
        //    {
        //        int nSub = n - this.NPeriods;
        //        this.MultiConductance.RemoveRange(this.NPeriods, nSub);
        //        this.MultiEndHead.RemoveRange(this.NPeriods, nSub);
        //        this.MultiHeadStage.RemoveRange(this.NPeriods, nSub);
        //        this.MultiStartHead.RemoveRange(this.NPeriods, nSub);
        //    }


        //    //this.NPeriods;

        //}



        public override void MapToModflow(List<double> stressPeriods, List<ValueResult> ijkList, ModFlow.Domain.DomainLayer.ModFlowData mf, FeatureObject owner)
        {
            if (ijkList.Count <= 0) return;
            int k = ijkList[0].K;

            List<int> indice = new List<int>();

            List<GeneralHead> GeneralHeads = new List<GeneralHead>();

            double TotalValue = owner.GetTotalLValue();

            //double currentLength = 0;

            foreach (ValueResult item in ijkList)
            {
                //if (item.K != k)
                //{
                //    k = item.K;
                //    currentLength = 0;
                //}
                indice.Add(mf.GridData.GetIndex(item.I, item.J, item.K));

                GeneralHead Gener = new GeneralHead(item.I, item.J, item.K, mf.GridData.RowsCount, mf.GridData.ColsCount, mf.GridData.LayersCount, mf.StressPeriods.InnerList.Count);


                if (owner is PointFO)
                {
                    this.assistMapToModFlow(stressPeriods, Gener.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, Gener.Head, _multiHeadStage);
                    

                    ////Gener.FirstConductance = this.Conductance;
                    ////Gener.FirstHead = this.HeadStage;
                    //for (int i = 0; i < this.NPeriods; i++)
                    //{ 
                    //Gener.Conductance[i]=this._multiConductance[i];
                    //Gener.Head[i] = this._multiHeadStage[i];
                    //}
                }

                if (owner is LineFO)
                {
                    List<double> starts = new List<double>(stressPeriods.Count);
                    List<double> ends = new List<double>(stressPeriods.Count);

                    foreach (var sp in stressPeriods)
                    {
                        starts.Add(0);
                        ends.Add(0);
                    }

                    this.assistMapToModFlow(stressPeriods, Gener.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, Gener.Head, _multiHeadStage);
                    this.assistMapToModFlow(stressPeriods, starts, _multiStartHead);
                    this.assistMapToModFlow(stressPeriods, ends, _multiEndHead);

                    for (int i = 0; i < Gener.NPeriods; i++)
                    {
                        Gener.Conductance[i] *= item.Value;
                        Gener.Head[i] = starts[i] + (ends[i] - starts[i]) * (item.LineCurrentTotalLength / TotalValue);

                    }


                    //for (int i = 0; i < this.NPeriods; i++)
                    //{
                    //    Gener.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    Gener.Head[i] = this._multiStartHead[i] + (this._multiEndHead[i] - this._multiStartHead[i]) * (item.LineCurrentTotalLength/ TotalValue);

                    //}
                    //currentLength += item.Value;
                }

                if (owner is PolygonFO)
                {
                    this.assistMapToModFlow(stressPeriods, Gener.Conductance, _multiConductance);
                    this.assistMapToModFlow(stressPeriods, Gener.Head, _multiHeadStage);

                    for (int i = 0; i < stressPeriods.Count; i++)
                    {
                        Gener.Conductance[i] *= item.Value;
                    }

                    //for (int i = 0; i < this.NPeriods; i++)
                    //{
                    //    Gener.Conductance[i] = this._multiConductance[i] * item.Value;
                    //    Gener.Head[i] = this._multiHeadStage[i];
                    //}
                }
                GeneralHeads.Add(Gener);
            }
            //mf.SourceSinks.GeneralHeads.UpdateGHB(GeneralHeads, indice);
            mf.SourceSinks.GeneralHeads.AddTempGeneralHeads(GeneralHeads);

        }
    }
}
